package cn.xinfei.xdecision.manager.controller.login;

import cn.xinfei.xdecision.common.model.common.ResponseEntityBuilder;
import cn.xinfei.xdecision.common.model.common.ResponseEntityDto;
import cn.xinfei.xdecision.common.model.login.AccountSessionWrap;
import cn.xinfei.xdecision.common.model.login.SSOUser;
import cn.xinfei.xdecision.common.model.login.SessionManager;
import cn.xinfei.xdecision.common.model.login.vo.LoginInfoParam;
import cn.xinfei.xdecision.common.service.common.sso.SSOService;
import cn.xinfei.xdecision.common.service.common.sso.dto.SSOCheckTokenReqDto;
import cn.xinfei.xdecision.common.service.common.sso.dto.SSOCheckTokenRespDto;
import cn.xinfei.xdecision.common.service.common.sso.dto.SSORespBody;
import cn.xinfei.xdecision.common.utils.constant.Constants;
import cn.xinfei.xdecision.common.utils.constant.OperateNameConst;
import cn.xinfei.xdecision.common.utils.constant.OperateTypeEnum;
import cn.xinfei.xdecision.common.utils.exception.enums.ErrorCodeEnum;
import cn.xinfei.xdecision.common.utils.util.JsonUtils;
import cn.xinfei.xdecision.manager.web.aop.ArchivesLog;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.common.utils.CollectionUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @apiDefine 对接公司sso权限系统
 */
@Api(tags = "权限管理-登录")
@Slf4j
@RestController("loginControllerV3")
@RequestMapping("/v3/auth/")
public class SSOLoginController {

    @Autowired
    private SSOService ssoService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @ResponseBody
    @RequestMapping(value = "/check-token", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ArchivesLog(type = OperateTypeEnum.OTHER, name = OperateNameConst.AuthOpt.LOGIN)
    @ApiOperation(value = "jdk-HashMap-动态创建显示参数-@RequestBody")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "body", dataType = "String", allowMultiple = true, name = "token", value = "token")
    })

    public ResponseEntityDto<Object> checkToken(@RequestBody LoginInfoParam token) {

        try {

            SSOCheckTokenReqDto ssoCheckTokenReqDto = new SSOCheckTokenReqDto();
            ssoCheckTokenReqDto.setToken(token.getToken());
            SSORespBody ssoRespBody = ssoService.checkToken(ssoCheckTokenReqDto);
            SSOCheckTokenRespDto ssoCheckTokenRespDto = JsonUtils.parseObject2(JSON.toJSONString(ssoRespBody.getData()), SSOCheckTokenRespDto.class);
            if (ssoCheckTokenRespDto != null && ssoCheckTokenRespDto.getUser() != null) {
                SSOUser user = ssoCheckTokenRespDto.getUser();
                JSONObject organ = ssoCheckTokenRespDto.getOrg();
                if (Objects.nonNull(organ) && organ.size() > 0) {
                    //设置当前组织id
                    user.setOrganId(organ.getLong("id"));
                } else {
                    return ResponseEntityBuilder.buildErrorResponse(ErrorCodeEnum.ORGAN_IS_NULL);
                }
                JSONArray orgList = ssoCheckTokenRespDto.getOrgList();
                if (CollectionUtils.isNotEmpty(orgList)) {
                    List<Long> orgIdList = new ArrayList<>();
                    orgList.forEach(org -> {
                        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(org));
                        //全部部门及子部门id
                        orgIdList.add(jsonObject.getLong("id"));
                    });
                    user.setOrgIdList(orgIdList);
                }
                stringRedisTemplate.opsForValue().set(token.getToken(), JSON.toJSONString(user));
                stringRedisTemplate.expire(token.getToken(), Constants.LOGIN_TOKEN_TIME.intValue(), TimeUnit.SECONDS);
                AccountSessionWrap acsw = new AccountSessionWrap(null, null);
                acsw.setSsoUser(user);
                SessionManager.setSession(acsw);
            } else {
                return ResponseEntityBuilder.buildErrorResponse(ErrorCodeEnum.LOGIN_ERROR);
            }
            return ResponseEntityBuilder.buildNormalResponse(ssoCheckTokenRespDto);
        } catch (Exception e) {
            log.error("登录异常，msg={}", e.getMessage(), e);
        }
        return ResponseEntityBuilder.buildErrorResponse(ErrorCodeEnum.LOGIN_ERROR);
    }
}
